﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive.Linq;
using System.Reflection;
using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using AvaloniaEdit;
using AvaloniaEdit.Search;
using Newtonsoft.Json;
using ReactiveUI;
using TCP232.PublicMethod;
using TCP232.ViewModels.UserControls;
using TCP232.Views.UserControls;

namespace TCP232.ViewModels
{
    public enum ClientType
    {
        SerialPort,
        Ethernet
    }

    public enum EthernetType
    {
        UDP,
        TCP_Server,
        TCP_Client
    }

    public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            Instance = this;
            for (int i = 0; i < 2; i++)
            {
                var clientType = (ClientType)i;
                var controlClient = new ControlClient();
                // controlClient.FindControl<DataGrid>("dgHistoryData").LoadingRow += (sender, e) => e.Row.Header = e.Row.GetIndex() + 1;
                var controlClientViewModel = new ControlClientViewModel(clientType, controlClient);
                controlClient.DataContext = controlClientViewModel;
                ClientList.Add(controlClient);
                _clients.TryAdd(clientType, controlClientViewModel);
                InitializationTextEditor(controlClient.FindControl<TextEditor>("txtMessage"));
            }
            OpenedCommand = ReactiveCommand.Create(ShowMessage, Observable.Return(true));
            //ClosedCommand = ReactiveCommand.Create(Closed);
            var assembly = Assembly.GetExecutingAssembly().GetName();
            Title = assembly.Name + "-V" + assembly.Version;
        }

        public MainWindowViewModel(Window mainWindow) : this()
        {
            MainWindow = mainWindow;
            MainWindow.Closed += delegate { Closed(); };
            if (File.Exists(SettingsFilePath))
            {
                try
                {
                    var json = File.ReadAllText(SettingsFilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        var jsonObject = JsonConvert.DeserializeObject<ConcurrentDictionary<ClientType, ControlClientViewModel>>(json);

                        //JsonConvert.PopulateObject(json, _clients, new JsonSerializerSettings()
                        //{
                        //    TypeNameHandling = TypeNameHandling.Auto,
                        //    ObjectCreationHandling = ObjectCreationHandling.Replace
                        //});
                         
                        foreach (var item in _clients)
                        {
                            var properties = item.Value.GetType().GetProperties().Where(x => x.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(JsonPropertyAttribute)) != null);
                            foreach (var property in properties)
                            {
                                if (jsonObject.TryGetValue(item.Key, out ControlClientViewModel controlClientViewModel))
                                {
                                    //var res = property.GetValue(controlClientViewModel);
                                    property.SetValue(item.Value, property.GetValue(controlClientViewModel));
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageTip.ShowError("读取配置文件出错：" + ex.Message);
                }
            }
        }

        public Window MainWindow { get; }

        public static MainWindowViewModel Instance { get; private set; }

        const string SettingsFilePath = "Settings.json";

        ConcurrentDictionary<ClientType, ControlClientViewModel> _clients = new();

        private string _title;

        public string Title
        {
            get => _title;
            set
            {
                _title = value;
                this.RaisePropertyChanged(nameof(Title));
            }
        }

        private bool _topmost;

        public bool Topmost
        {
            get => _topmost;
            set
            {
                _topmost = value;
                this.RaisePropertyChanged(nameof(Topmost));
            }
        }

        private string _greeting = "Welcome to Avalonia!";

        public string Greeting
        {
            get => _greeting;
            set
            {
                _greeting = value;
                this.RaisePropertyChanged(nameof(Greeting));
            }
        }

        public ICommand OpenedCommand { get; }
        //public ICommand ClosedCommand { get; }
        public List<ControlClient> ClientList { get; set; } = new List<ControlClient>();

        // private ObservableCollection<UserControl> socketServerList = new ObservableCollection<UserControl>();
        // public ObservableCollection<UserControl> SocketServerList
        // {
        //     get => socketServerList;
        //     set { socketServerList = value; this.RaiseAndSetIfChanged(ref socketServerList,value); }
        // }

        public void ShowMessage()
        {
            //    int a = 0; 
            //MessageTip.Show("Avalonia");
            // MessageBoxManager.GetMessageBoxStandardWindow("Avalonia", "1234567890").ShowDialog(MainWindow);
        }

        public void Closed()
        {
            _clients.SaveAsJsonToFile(SettingsFilePath);
        }

        public void About()
        {
            MessageTip.Show("Avalonia Version:0.10.21\r\n.NET Version:6.0");
        }

        private ISolidColorBrush TabItemHeaderForeground
        {
            get => Application.Current.Resources[nameof(TabItemHeaderForeground)] as ISolidColorBrush;
            set => Application.Current.Resources[nameof(TabItemHeaderForeground)] = value;
        }

        private ISolidColorBrush TabItemHeaderBackground
        {
            get => Application.Current.Resources[nameof(TabItemHeaderBackground)] as ISolidColorBrush;
            set => Application.Current.Resources[nameof(TabItemHeaderBackground)] = value;
        }

        private ISolidColorBrush GroupBoxHeaderBackground
        {
            get => Application.Current.Resources[nameof(GroupBoxHeaderBackground)] as ISolidColorBrush;
            set => Application.Current.Resources[nameof(GroupBoxHeaderBackground)] = value;
        }

        public void SwitchTheme(string type)
        {
            var url = new Uri($"avares://Avalonia.Themes.Default/Accents/Base{type}.xaml");
            StyleInclude styleInclude = new StyleInclude(url);
            styleInclude.Source = url;
            if (Application.Current.Styles[0] is StyleInclude style && style.Source != styleInclude.Source)
            {
                Application.Current.Styles[0] = styleInclude;
            }

            ISolidColorBrush background = type == "Dark" ? SolidColorBrush.Parse("#282828") : Brushes.White;
            if (GroupBoxHeaderBackground.Color != background.Color)
            {
                GroupBoxHeaderBackground = background;
            }

            ISolidColorBrush foreground = type == "Dark" ? Brushes.White : Brushes.Black;
            if (TabItemHeaderForeground.Color != foreground.Color)
            {
                TabItemHeaderForeground = foreground;
            }

            ISolidColorBrush tabItemHeaderBackground = type == "Dark" ? Brushes.Gray : Brushes.LightGray;
            if (TabItemHeaderBackground.Color != tabItemHeaderBackground.Color)
            {
                TabItemHeaderBackground = tabItemHeaderBackground;
            }
        }

        public void InitializationTextEditor(TextEditor textEditor)
        {
            List<MenuItem> items = new List<MenuItem>();
            var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
            SearchPanel.Install(textEditor);
            ContextMenu contextMenu = new ContextMenu();

            MenuItem copyMenuItem = new MenuItem();
            copyMenuItem.Icon = new Image() { Source = new Bitmap(assets.Open(new Uri("avares://TCP232/Assets/Image/copy.png"))) };
            copyMenuItem.Header = "复制(Ctrl+C)";
            copyMenuItem.Click += (sender, e) => textEditor.Copy();
            items.Add(copyMenuItem);

            MenuItem pasteMenuItem = new MenuItem();
            pasteMenuItem.Header = "粘贴(Ctrl+V)";
            pasteMenuItem.Click += (sender, e) => textEditor.Paste();
            items.Add(pasteMenuItem);
            MenuItem cutMenuItem = new MenuItem();
            cutMenuItem.Header = "剪切(Ctrl+X)";
            cutMenuItem.Click += (sender, e) => textEditor.Cut();
            items.Add(cutMenuItem);

            MenuItem selectAllItem = new MenuItem();
            selectAllItem.Header = "全选(Ctrl+A)";
            selectAllItem.Click += (sender, e) => textEditor.SelectAll();
            items.Add(selectAllItem);
            //contextMenu.Items.Add(selectAllItem);
            contextMenu.Items = items;
            textEditor.ContextMenu = contextMenu;


            // textEditor.TextArea.VerticalAlignment = VerticalAlignment.Center;
            // textEditor.TextArea.SelectionForeground= Brushes.Red;
            // textEditor.TextArea.SelectionBrush= SolidColorBrush.Parse("#4CA0E3");
        }
    }
}